package cn.enilu.flash.api.controller.mini;

/**
 * @Description
 * @Author Spark
 * @Date Created in (2020/04/16 14:18)
 * @Version v1.0
 * @Modify
 **/

import cn.enilu.flash.api.constant.WxApiConstant;
import cn.enilu.flash.api.controller.BaseController;
import cn.enilu.flash.api.utils.GsonUtil;
import cn.enilu.flash.api.utils.HttpClientUtil;
import cn.enilu.flash.bean.constant.cache.Cache;
import cn.enilu.flash.bean.constant.cache.CacheKey;
import cn.enilu.flash.bean.core.BussinessLog;
import cn.enilu.flash.bean.dictmap.CommonDict;
import cn.enilu.flash.bean.dto.mini.WxLoginDto;
import cn.enilu.flash.bean.dto.mini.WxSessionDto;
import cn.enilu.flash.bean.entity.cust.CustInfo;
import cn.enilu.flash.bean.vo.front.Rets;
import cn.enilu.flash.bean.vo.query.SearchFilter;
import cn.enilu.flash.cache.CacheDao;
import cn.enilu.flash.core.log.LogManager;
import cn.enilu.flash.core.log.LogTaskFactory;
import cn.enilu.flash.enums.body.LogClientType;
import cn.enilu.flash.enums.body.State;
import cn.enilu.flash.security.JwtUtil;
import cn.enilu.flash.service.cust.CustInfoService;
import cn.enilu.flash.utils.HttpKit;
import cn.enilu.flash.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

/**
 * @Description 小程序登录
 * @Author Spark
 * @Date Created in (2019/08/26 18:15)
 * @Version v1.0
 * @Modify
 **/
@Slf4j
@RestController
@RequestMapping(value = "/mini/account", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public class LoginController extends BaseController {
    @Autowired
    private CacheDao cacheDao;
    @Autowired
    private HttpClientUtil httpUtil;
    @Autowired
    private CustInfoService custInfoService;
    /**
     * @Description 根据前端小程序传入的code, 从微信服务端获取openId和sessionKey等相关信息
     * @Author  Spark
     * @Date    Created in (2019/08/27 14:19)
     * @param	code
     * @Return  com.lee.spark.module.demo1.dto.WxSessionDto
     * @Version v1.0
     * @Modify
     **/
    @GetMapping(value = "/getWxSessionInfo/{code}")
    public Object getWxSessionInfo(@PathVariable("code") String code) throws Exception{
        String api = String.format(WxApiConstant.WX_API_GET_SESSION_KEY, WxApiConstant.WX_APP_ID, WxApiConstant.WX_APP_SECRET, code);
        String resJson = httpUtil.get(WxApiConstant.WX_API_BASE + api);
        log.info("----res:{}", resJson);
        return Rets.success(GsonUtil.fromJson(resJson, WxSessionDto.class));
    }

    /**
     * @Description 模拟发送短信验证码
     * @Author  Spark
     * @Date    Created in (2020/04/20 15:56)
     * @param	mobile
     * @Return  java.lang.Object
     **/
    @GetMapping(value = "/getCode/{mobile}")
    public Object getCode(@PathVariable("mobile") String mobile) throws Exception{
        if(StringUtils.isNullOrEmpty(mobile) || mobile.length() != 11){
            return Rets.failure("手机号码不正确");
        }
        CustInfo custInfo = custInfoService.get(new SearchFilter("mobile", SearchFilter.Operator.EQ, mobile));
        if(custInfo == null){
            return Rets.failure("手机号不存在");
        }
        if(custInfo.getState() != State.ACTIVE.getCode()){
            return Rets.failure("客户状态无效");
        }
        String code = String.valueOf(1000+(int)(Math.random()*(9999-1000+1)));
        log.info(">>>>>>>>>>>验证码 code={}", code);
        //TODO 调用短信接口

        //放入缓存
        cacheDao.hset(Cache.TEMP, CacheKey.MINI_VCODE + mobile, code);
        return Rets.success(code);
    }

    /**
     * @Description 登录
     * @Author  Spark
     * @Date    Created in (2020/04/21 9:57)
     * @param	dto
     * @Return  java.lang.Object
     **/
    @PostMapping(value = "login")
    @BussinessLog(value = "小程序标准登录", key = "mobile",dict= CommonDict.class)
    public Object login(@RequestBody WxLoginDto dto){
        log.info(">>>>>> phone:{}", dto.getPhone());
        log.info(">>>>>> vcode:{}", dto.getCode());
        String code = cacheDao.hget(Cache.TEMP, CacheKey.MINI_VCODE + dto.getPhone(), String.class);
        if(!StringUtils.equals(dto.getCode(), code)){
            return Rets.failure("验证码错误");
        }
        CustInfo custInfo = custInfoService.get(new SearchFilter("mobile", SearchFilter.Operator.EQ, dto.getPhone()));
        if(custInfo == null){
            return Rets.failure("手机号不存在");
        }
        if(custInfo.getState() != State.ACTIVE.getCode()){
            return Rets.failure("客户状态无效");
        }
        String token = JwtUtil.sign(custInfo);
        Map<String, String> result = new HashMap<>(1);
        log.info("miniApp token:{}",token);
        result.put("token", token);
        result.put("mobile", custInfo.getMobile());
        result.put("name", custInfo.getName());
        //记录登录日志
        LogManager.me().executeLog(LogTaskFactory.loginLog(custInfo.getId(), LogClientType.MINI_APP.getCode(), HttpKit.getIp()));

        return Rets.success(result);
    }

    @PostMapping(value = "loginForToken")
    @BussinessLog(value = "小程序token登录", key = "mobile",dict= CommonDict.class)
    public Object loginForToken(){
        String token = HttpKit.getMiniToken();
        if(StringUtils.isNullOrEmpty(token)){
            return Rets.failure("令牌已过期，需要重新登录");
        }
        CustInfo cust = custInfoService.get(new SearchFilter("mobile", SearchFilter.Operator.EQ, JwtUtil.getCustMobile()));
        if(cust == null){
            return Rets.failure("手机号不存在");
        }
        if(cust.getState() != State.ACTIVE.getCode()){
            return Rets.failure("客户状态无效");
        }
        Map<String, String> result = new HashMap<>(1);
        log.info("miniApp token:{}",token);
        result.put("token", token);
        result.put("mobile", cust.getMobile());
        result.put("name", cust.getName());
        //记录登录日志
        LogManager.me().executeLog(LogTaskFactory.loginLog(cust.getId(), LogClientType.MINI_APP.getCode(), HttpKit.getIp()));

        return Rets.success(result);
    }

    @PostMapping(value = "logoff")
    public Object logoff(){
        String token = HttpKit.getMiniToken();
        if(StringUtils.isNotNullOrEmpty(token)){
            try {
                CustInfo cust = custInfoService.get(new SearchFilter("mobile", SearchFilter.Operator.EQ, JwtUtil.getCustMobile()));
                LogManager.me().executeLog(LogTaskFactory.exitLog(cust.getId(), LogClientType.MANAGER.getCode(), HttpKit.getIp()));
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        //记录登录日志
        return Rets.success();
    }
}
